package com.blue.http.util;

import java.io.File;
import java.io.FileOutputStream;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.List;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.X509TrustManager;

import org.apache.http.Consts;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.StatusLine;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.blue.http.client.DownloadResult;

public class HttpClientUtil
{
	private static Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);
	
	private HttpClientUtil()
	{
	}
	
	/**
	 * 返回 HTTP 响应字符串
	 * 
	 * @param response
	 * @return
	 */
	public static String toString(HttpResponse response) throws HttpException
	{
		String resp = null;
		try
		{
			resp = EntityUtils.toString(response.getEntity(), Consts.UTF_8);
		}
		catch (Exception e)
		{
			logger.error("EntityUtils.toString() 有错误 - ", e);
		}

		StatusLine statusLine = response.getStatusLine();
		if (statusLine.getStatusCode() != HttpStatus.SC_OK) // http调用失败
		{
			logger.error("错误信息：{}", resp);
			throw new HttpException(statusLine.getStatusCode(), statusLine.getReasonPhrase());
		}
		return resp;
	}
	
	/**
	 * HTTP 下载保存成文件
	 * 
	 * @param response
	 * @param file
	 * @return
	 */
	public static DownloadResult toFile(HttpResponse response, File file) throws HttpException
	{
		File dir = file.getParentFile();
		if (!dir.exists())
		{
			if (!dir.mkdirs())
				throw new HttpException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "创建目录失败：" + dir.getAbsolutePath());
		}
		
		StatusLine statusLine = response.getStatusLine();
		if (statusLine.getStatusCode() != HttpStatus.SC_OK) // http调用失败
			throw new HttpException(statusLine.getStatusCode(), "下载失败：" + statusLine.getReasonPhrase());
		
		HttpEntity entity = response.getEntity();
		String resp = null;
		try
		{
			resp = EntityUtils.toString(entity, Consts.UTF_8);
		}
		catch (Exception e)
		{
			logger.error("EntityUtils.toString() 有错误 - ", e);
		}
		if (!entity.isStreaming())
			throw new HttpException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "下载失败：" + resp);
		
		DownloadResult result = new DownloadResult();
		result.setSize((int)entity.getContentLength());
		Header type = entity.getContentType();
		logger.debug(type.toString());
		if (type != null)
		{
			int pos = type.getValue().indexOf(';');
			if (pos == -1)
				result.setMimeType(type.getValue());
			else
				result.setMimeType(type.getValue().substring(0, pos));
		}
		try (FileOutputStream fos = new FileOutputStream(file);)
		{
			entity.writeTo(fos);
		}
		catch (Exception e)
		{
			logger.error("Entity.writeTo() 有错误 - ", e);
		}
		return result;
	}

	public static <T> T toObject(Class<T> clazz, String json)
	{
		T obj = JSON.parseObject(json, clazz);
		return obj;
	}

	public static <T> List<T> toList(Class<T> clazz, String json)
	{
		List<T> list = JSON.parseObject(json, new TypeReference<List<T>>(clazz){});
		return list;
	}

	public static void trustCert() throws NoSuchAlgorithmException, KeyManagementException
	{
		X509TrustManager[] manager = new X509TrustManager[] { new DefaultTrustManager() };
		SSLContext ctx = SSLContext.getInstance("SSL");
		ctx.init(null, manager, null);
		HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
		HttpsURLConnection.setDefaultHostnameVerifier(new DefaultHostnameVerifier());
	}

}
